﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Newtonsoft.Json.Linq;

namespace AppFuscator
{
    public enum State
    {
        Processing,
        Success,
        Error
    }

    public enum MessageKind
    {
        Notice,
        Warning,
        Error,
        Success
    }

    public class Message
    {
        public MessageKind Kind { get; set; }
        public string Text { get; set; }

        public Message(string k, string text)
        {
            switch (k)
            {
                case "warning":
                    Kind = MessageKind.Warning;
                    break;
                case "notice":
                    Kind = MessageKind.Notice;
                    break;
                case "finished":
                    Kind = MessageKind.Success;
                    break;
                default:
                    Kind = MessageKind.Error;
                    break;
            }
            Text = text;
        }

        public override string ToString()
        {
            return Text;
        }
    }

    public class AppfuscatorResult
    {
        public int obfuscationId;
        public List<string> Files;
        public List<Message> Log;

        public State State { get; set; }

        public AppfuscatorResult()
        {
            Files = new List<string>();
            Log = new List<Message>();
        }

        public static AppfuscatorResult Create(string result)
        {
            var ret = new AppfuscatorResult();

            var root = JObject.Parse(result);
            var st = root.Property("state").Value.ToString();
            switch (st)
            {
                case "Done":
                    ret.State = State.Success;
                    break;
                case "Initialized":
                case "Uploading":
                case "Running":
                case "ProcessingFinished":
                case "Downloading":
                    ret.State = State.Processing;
                    break;
                default:
                    ret.State = State.Error;
                    break;
            }

            var fs = root.Property("files").Value as JArray;
            var lgs = root.Property("log").Value as JArray;
            ret.obfuscationId = int.Parse(root.Property("id").Value.ToString());

            ret.Files = new List<string>();
            ret.Log = new List<Message>();

            foreach (var it in fs)
            {
                string tp = (it as Newtonsoft.Json.Linq.JValue).Value.ToString();
                tp = tp.Substring(tp.LastIndexOf("/")+1);
                ret.Files.Add(tp.ToString());
            }

            foreach (var it in lgs)
            {
                var tp = (it as Newtonsoft.Json.Linq.JObject).Property("type");
                var tx = (it as Newtonsoft.Json.Linq.JObject).Property("text");
                ret.AddToLog(tp.Value.ToString(), tx.Value.ToString());
            }

            return ret;
        }

        public void AddToLog(string tp, string tx)
        {
         
            Log.Add(new Message(tp.ToLower(), tx));
        }

        public string ZipFileUrl
        {
            get
            {
                if (Files == null) return null;

                foreach (var it in Files)
                {
                    if (Path.GetExtension(it) == ".zip")
                        return MakeUrl(it);
                }
                return null;
            }
        }

        public string MakeUrl(string name)
        {
            if (name == null) return null;
            if (name.IndexOf("://") > -1)
                return name;
            else
                return "http://" + name;
        }

        public string TextState
        {
            get
            {
                switch (State)
                {
                    case State.Processing:
                        return "Processing";
                    case State.Success:
                        return "Completed";
                    case State.Error:
                        return "Processing errors occurred";
                    default:
                        return "";                        
                }
            }
        }
    }
}
